package com.tea.zxql.listener;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.tea.zxql.domain.Sim;
import com.tea.zxql.mapper.SimMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * @ClassDescription: 监听 Redis 中 key 过期事件的监听器实现类。主要用于处理用户在线状态和 SIM 卡相关信息的清理逻辑。
 * @ClassName: ExpiredMessageListenerImpl
 * @JdkVersion: 17
 * @Author: HYC
 * @Created: 2025/8/6 11:56
 * @Version 1.0
 */
@Component
public class ExpiredMessageListenerImpl extends KeyExpirationEventMessageListener {


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private SimMapper simMapper;

    /**
     * 构造方法，初始化父类监听容器
     *
     * @param listenerContainer Redis 消息监听容器
     */
    public ExpiredMessageListenerImpl(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }


    /**
     * 处理 Redis key 过期事件的核心方法。
     * 根据过期 key 的前缀判断是用户在线状态还是 SIM 卡在线状态，并执行相应的登出逻辑。
     *
     * @param message 包含过期 key 的消息体
     * @param pattern 匹配模式（未使用）
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 获取失效的key, online:81
        String key = message.toString();
        System.out.println("key:" + key);

        // 判断 key 是否为用户在线状态标识
        if (key.startsWith("online:")) {
            String loginId = key.substring(7);
            logout(Integer.parseInt(loginId), null);
        }
        // 判断 key 是否为 SIM 卡在线状态标识
        else if (key.startsWith("sim.online:")) {
            String simId = key.substring(11);
            String userId = redisTemplate.opsForValue().get(simId + "userId"); // null
            logout(userId == null ? null : Integer.parseInt(userId), simId);
        }

    }


    /**
     * 执行登出操作，清除 Redis 中与用户和 SIM 卡相关的缓存数据，并更新数据库中 SIM 卡的状态。
     *
     * @param userId 用户 ID，可能为 null
     * @param simId  SIM 卡 ID，不能为空
     */
    public void logout(Integer userId, String simId) {

        // 如果 simId 为空，则尝试从 Redis 中获取
        if (simId == null) {
            // 此处的userId一定不为空
            simId = redisTemplate.opsForValue().get(userId + "userIdGetsimId:");
        }

        // 清除 Redis 中绑定的数据
        redisTemplate.delete(simId + "company");
        redisTemplate.delete(simId + "userId");

        if (userId != null) {
            redisTemplate.delete(userId + "userIdGetsimId:");
        }

        redisTemplate.delete(simId + ".buzzer");
        redisTemplate.delete(simId + ".led");
        redisTemplate.delete(simId + ".old.buzzer");
        redisTemplate.delete(simId + ".old.led");

        // 删除或更新数据库中的 SIM 卡记录
        simMapper.delete(new LambdaQueryWrapper<Sim>().eq(Sim::getSimId, simId));
        simMapper.update(new LambdaUpdateWrapper<Sim>()
                .set(Sim::getStatus, 0)
                .eq(Sim::getSimId, simId));

        // 如果用户 ID 不为空，则调用 StpUtil 登出该用户
        if (userId != null) {
            StpUtil.logout(userId);
        }
    }

}
